/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package test;

import dsa.LinkedList;
import org.junit.*;
import static org.junit.Assert.*;

/**
 *JUnit Class DavidRosenLinkedTest tests all methods and operations in class LinkedList.
 * 
 * @author David
 * @version 5
 */
public class DavidRosenTest {

    private LinkedList list1;

    public DavidRosenTest() {
    }

    @Before
    public void setUp() {
        System.out.println("* UtilsJUnit4Test: @Before method");

        list1 = new LinkedList();

        list1.addLast(1);
        list1.addLast(2);
        list1.addLast(3);
        list1.addLast("a");
        list1.addLast("b");
        list1.addLast(1);
        list1.addLast(2);
        list1.addLast(3);
        list1.addLast("a");
        list1.addLast("b");
        list1.addLast(1);
        list1.addLast(2);
        list1.addLast(3);
        list1.addLast("a");
        list1.addLast("b");
        list1.addLast(1);
        list1.addLast(2);
        list1.addLast(3);
        list1.addLast("a");
        list1.addLast("b");
        list1.addLast(1);
        list1.addLast(2);
        list1.addLast(3);
        list1.addLast("a");
        list1.addLast("b");
        list1.addLast(1);
        list1.addLast(2);
        list1.addLast(3);
        list1.addLast("a");
        list1.addLast("b");
    }

    @After
    public void tearDown() {
        list1 = new LinkedList();
    }

    /**
     * Test of get method, of class LinkedList.
     */
    @Test
    public void testGet() {
        System.out.println("get");
        int index = 4;
        Object expResult = "b";
        Object result = list1.get(index);
        assertEquals(expResult, result);

        index = 20;
        expResult = 1;
        result = list1.get(index);
        assertEquals(expResult, result);

        index = 18;
        expResult = "a";
        result = list1.get(index);
        assertEquals(expResult, result);

        list1.addFirst(5);
        index = 4;
        expResult = "a";
        result = list1.get(index);
        assertEquals(expResult, result);

        index = 20;
        expResult = "b";
        result = list1.get(index);
        assertEquals(expResult, result);

        index = 18;
        expResult = 3;
        result = list1.get(index);
        assertEquals(expResult, result);

        list1.addLast(5);
        index = 4;
        expResult = "a";
        result = list1.get(index);
        assertEquals(expResult, result);

        index = 20;
        expResult = "b";
        result = list1.get(index);
        assertEquals(expResult, result);

        index = 18;
        expResult = 3;
        result = list1.get(index);
        assertEquals(expResult, result);

        index = 0;
        expResult = 5;
        result = list1.get(index);
        assertEquals(expResult, result);

        index = 31;
        expResult = 5;
        result = list1.get(index);
        assertEquals(expResult, result);

        list1.set(3, 45);
        assertEquals(45, list1.get(3));
        
        list1.set(16, 45);
        assertEquals(45, list1.get(16));
        
        list1.set(21, 45);
        assertEquals(45, list1.get(21));
    }

    /**
     * Test of getFirst method, of class LinkedList.
     */
    @Test
    public void testGetFirst() {
        System.out.println("getFirst");
        assertEquals(1, list1.getFirst());

        list1.addFirst("F");
        assertEquals("F", list1.getFirst());

        list1.addLast("L");
        list1.addLast("L");
        list1.addFirst("First");
        assertEquals("First", list1.getFirst());
    }

    /**
     * Test of getLast method, of class LinkedList.
     */
    @Test
    public void testGetLast() {
        System.out.println("getLast");
        assertEquals("b", list1.getLast());

        list1.addFirst("F");
        assertEquals("b", list1.getLast());

        list1.addLast("L");
        list1.addLast("Last");
        list1.addFirst("First");
        assertEquals("Last", list1.getLast());
    }

    /**
     * Test of size method, of class LinkedList.
     */
    @Test
    public void testSize() {
        System.out.println("size");
        assertEquals(30, list1.size());

        list1.addFirst("F");
        list1.addFirst("F");
        assertEquals("addFirst() Caused Errors when checking size()", 32, list1.size());

        list1.addLast("L");
        list1.addLast("L");
        list1.addLast("L");
        assertEquals("addLast() Caused Errors when checking size()", 35, list1.size());

        list1.remove(5);
        list1.remove(8);
        assertEquals("Remove() Caused Error when checking size()", 33, list1.size());

        list1.set(4, "S");
        list1.set(25, "S");
        assertEquals("set() Caused Error when checking size()", 33, list1.size());
        
        list1.addFirst("F");
        list1.addFirst("F");
        list1.addLast("L");
        list1.set(7, "S");
        list1.addFirst("F");
        list1.remove(35);
        assertEquals(36, list1.size());
    }

    /**
     * Test of addFirst method, of class LinkedList.
     */
    @Test
    public void testAddFirst() {
        System.out.println("addFirst");
        list1.addFirst("v");
        assertEquals("v", list1.getFirst());

        list1.removeFirst();
        list1.addFirst("AF");
        assertEquals("removeFirst() caused errors","AF", list1.getFirst());
        
        list1.removeLast();
        list1.addFirst("AF");
        assertEquals("removeLast() caused errors","AF", list1.getFirst());

        list1.removeFirst();
        list1.removeLast();
        list1.addFirst("AF");
        list1.addFirst("AB");
        list1.addFirst("AC");
        assertEquals("removeLast() caused errors","AC", list1.get(0));
    }

    /**
     * Test of addLast method, of class LinkedList.
     */
    @Test
    public void testAddLast() {
        System.out.println("addLast");
        list1.addLast("x");
        assertEquals("x", list1.getLast());
        
        list1.removeFirst();
        list1.addLast("AL");
        assertEquals("removeFirst() caused errors","AL", list1.getLast());
        
        list1.removeLast();
        list1.addLast("AL");
        assertEquals("removeLast() caused errors","AL", list1.getLast());

        list1.removeFirst();
        list1.removeLast();
        list1.addLast("AL");
        list1.addLast("AB");
        list1.addLast("AC");
        assertEquals("removeLast() caused errors","AC", list1.get(31));
    }

    /**
     * Test of remove method, of class LinkedList.
     */
    @Test
    public void testRemove() {
        System.out.println("remove");

        assertEquals(3, list1.remove(2));
        assertEquals(1, list1.remove(19));
        assertEquals("b", list1.remove(27));
        
        list1.addFirst("F");
        assertEquals("addFirst() caused errors","F", list1.remove(0));
        assertEquals("remove() caused errors",1, list1.get(0));
        
        list1.addLast("L");
        assertEquals("addLast() caused errors","L", list1.remove(27));
        assertEquals("remove() caused errors","a", list1.getLast());
        
        list1.addFirst(3);
        list1.addFirst(2);
        list1.addLast(4);
        list1.addFirst(1);
        list1.addLast(5);
        list1.addLast(6);
        list1.addLast(7);
        list1.addLast(8);
        assertEquals(1, list1.remove(0));
        assertEquals(3, list1.remove(1));
        assertEquals(5, list1.remove(29));
        assertEquals(8, list1.remove(32));
    }

    /**
     * Test of removeFirst method, of class LinkedList.
     */
    @Test
    public void testRemoveFirst() {
        System.out.println("removeFirst");
        assertEquals(1, list1.removeFirst());
        assertEquals("removeFirst() cause error", 2, list1.getFirst());
        
        list1.addFirst("A");
        list1.addFirst("B");
        list1.addFirst("C");
        assertEquals("addFirst() caused errors","C", list1.removeFirst());
        assertEquals("removeFirst() cause error", "B", list1.getFirst());
    }

    /**
     * Test of removeLast method, of class LinkedList.
     */
    @Test
    public void testRemoveLast() {
        System.out.println("removeLast");
        assertEquals("b", list1.removeLast());
        assertEquals("removeLast() cause error", "a", list1.getLast());
        
        list1.addLast("A");
        list1.addLast("B");
        list1.addLast("C");
        assertEquals("addFirst() caused errors","C", list1.removeLast());
        assertEquals("removeFirst() cause error", "B", list1.getLast());
    }

    /**
     * Test of indexOf method, of class LinkedList.
     */
    @Test
    public void testIndexOf() {
        System.out.println("indexOf");
        assertEquals(2, list1.indexOf(3));
        assertEquals(-1, list1.indexOf(6));
        
        list1.addLast("Last");
        assertEquals("addLast() caused errors",30, list1.indexOf("Last"));
        
        list1.addFirst("First");
        assertEquals("addFirst() caused errors",0, list1.indexOf("First"));
    }

    /**
     * Test of contains method, of class LinkedList.
     */
    @Test
    public void testContains() {
        System.out.println("contains");
        assertEquals(true, list1.contains(2));
        assertEquals(false, list1.contains("g"));
        
        list1.addFirst("First");
        assertEquals("addFirst() caused errors",true, list1.contains("First"));
        
        list1.addLast("Last");
        assertEquals("addLast() caused errors",true, list1.contains("Last"));
    }

    /**
     * Test of clone method, of class LinkedList.
     */
    @Test
    public void testClone() {
        System.out.println("clone");
        LinkedList resultList = (LinkedList)list1.clone();

        for (int i = 0; i < list1.size(); i++) {
            assertEquals(list1.get(i), resultList.get(i));
        }
        
        list1.addFirst("First");
        list1.addFirst("Last");
        assertEquals(false, resultList.contains("First"));
        assertEquals(false, resultList.contains("Last"));
        
        resultList.addFirst("First");
        resultList.addLast("Last");
        assertEquals(true, resultList.contains("First"));
        assertEquals(true, resultList.contains("Last"));
        
        resultList.set(20, "Set");
        assertEquals(false, list1.contains("Set"));
        assertEquals(true, resultList.contains("Set"));
    }

    /**
     * Test of set method, of class LinkedList.
     */
    @Test
    public void testSet() 
    {
        System.out.println("set");
        Object setResult = list1.set(3, "R");
        assertEquals("a", setResult);
 
        assertEquals(1, list1.set(20,"R"));
    
        assertEquals("R", list1.get(3));
        assertEquals("R", list1.get(20));
    }
     
     /**
     * Test of toArray method, of class LinkedList.
     */
    @Test
    public void testToArray() {
        System.out.println("toArray");
        Object[] resultArray = list1.toArray();
        assertArrayEquals(resultArray, list1.toArray());
        
        for (int i = 0; i < list1.size(); i++)
        {
            assertEquals(resultArray[i], list1.toArray()[i]);
        }
        
        list1.remove(5);
        list1.remove(20);
        list1.removeFirst();
        list1.removeLast();
        
        resultArray = list1.toArray();
        
        assertArrayEquals("remove() method caused error",resultArray, list1.toArray());
        
        for (int i = 0; i < list1.size(); i++)
        {
            assertEquals(resultArray[i], list1.toArray()[i]);
        }
    }
    
    /**
     * Test of equals method, of class LinkedList.
     */
    @Test
    public void testEquals() {
        System.out.println("equals");
        LinkedList resultList = (LinkedList)list1.clone();
        
        assertTrue(list1.equals(resultList));
        
        assertTrue(resultList.equals(list1));
        
        resultList.set(20, "Fail");
        resultList.set(25, "Fail");
        resultList.set(4, "Fail");
        
        assertFalse("Method set() caused errors when checking list1 "
                + "against resultList",list1.equals(resultList));
        assertFalse("Method set() caused errors when checking resultList "
                + "against list1", resultList.equals(list1));
        
        resultList.removeFirst();
        resultList.removeLast();
        assertFalse(list1.equals(resultList));
        assertFalse(resultList.equals(list1));
    }
    
    /**
     * Test of add method, in sub-class LinkedListIterator of class LinkedList.
     */
    @Test
    public void testIteratorAdd() {
        System.out.println("Iterator add");
        ListIterator iterate = list1.listIterator(0);
        
        iterate.add("first");
        
        assertTrue(list1.contains("first"));
        assertEquals(0, list1.indexOf("first"));
        
        iterate.next();
        iterate.next();
        iterate.next();
        iterate.next();
        iterate.next();
        
        iterate.add("LAST");
        
        assertTrue(list1.contains("LAST"));
        assertEquals(6, list1.indexOf("LAST"));
    }
    
    /**
     * Test of next method, in sub-class LinkedListIterator of class LinkedList.
     */
    @Test
    public void testIteratorNext() {
        System.out.println("Iterator next");
        
        ListIterator iterate = list1.listIterator(0);
        
        assertEquals(1,iterate.next());
        
        Object value = iterate.next();
        assertTrue(iterate.hasNext());
        
        assertEquals(2 , value);
    }
    
    /**
     * Test of hasNext method, in sub-class LinkedListIterator of class LinkedList.
     */
    @Test
    public void testIteratorHasNext() {
        System.out.println("Iterator hasNext");
        
        ListIterator iterate = list1.listIterator(0);
        
        assertTrue(iterate.hasNext());
        
        iterate.next();
        assertTrue(iterate.hasNext());
        
        iterate.previous();
        
        for(int i = 0; i < list1.size(); i++)
        {
            if(iterate.hasNext())
            {
                iterate.next();
            }
            else
            {
                assertEquals(null, iterate.next());
                assertFalse(iterate.hasNext());
            }
        }
    }
    
    /**
     * Test of nextIndex method, in sub-class LinkedListIterator of class LinkedList.
     */
    @Test
    public void testIteratorNextIndex() {
        System.out.println("Iterator nextIndex");
        
        ListIterator iterate = list1.listIterator(3);
        
        assertEquals(3, iterate.nextIndex());
        
        iterate.next();
        iterate.next();
        iterate.next();
        iterate.next();
        
        assertEquals( 7,iterate.nextIndex());
        
        iterate.previous();
        iterate.previous();
        assertEquals( 5,iterate.nextIndex());
    }
    
    /**
     * Test of previous method, in sub-class LinkedListIterator of class LinkedList.
     */
    @Test
    public void testIteratorPrevious() {
        System.out.println("Iterator previous");
        
        ListIterator iterate = list1.listIterator(3);
        
        assertEquals(3,iterate.previous());
        
        Object value = iterate.previous();
        assertTrue(iterate.hasPrevious());
        
        assertEquals(2 , value);
    }
    
    /**
     * Test of hasPrevious method, in sub-class LinkedListIterator of class LinkedList.
     */
    @Test
    public void testIteratorHasPrevious() {
        System.out.println("Iterator hasPrevious");
        
        ListIterator iterate = list1.listIterator(0);
        
        assertFalse(iterate.hasPrevious());
        
        iterate.next();
        
        assertTrue(iterate.hasPrevious());
        
        iterate.next();
        iterate.next();
        assertTrue("Iterator method next() caused errors", iterate.hasPrevious());
    }
    
    /**
     * Test of previousIndex method, in sub-class LinkedListIterator of class LinkedList.
     */
    @Test
    public void testIteratorPreviousIndex() {
        System.out.println("Iterator previousIndex");
        
        ListIterator iterate = list1.listIterator(3);
        
        assertEquals(2, iterate.previousIndex());
        
        iterate.next();
        iterate.next();
        iterate.next();
        iterate.next();
        
        assertEquals(6, iterate.previousIndex());
        
        iterate.previous();
        iterate.previous();
        assertEquals(4, iterate.previousIndex());
    }
    
    /**
     * Test of remove method, in sub-class LinkedListIterator of class LinkedList.
     */
    @Test
    public void testIteratorRemove() {
        System.out.println("Iterator remove");
        
        ListIterator iterate = list1.listIterator(3);
        
        assertEquals("a", iterate.next());
        
        iterate.remove();
        
        assertEquals(3, iterate.previous());
        assertEquals(2, iterate.previous());
        assertEquals(2, iterate.next());
        
        iterate.remove();
        
        assertTrue(iterate.hasNext());
        assertTrue(iterate.hasPrevious());
    }
    
    /**
     * Test of set method, in sub-class LinkedListIterator of class LinkedList.
     */
    @Test
    public void testIteratorSet() {
        System.out.println("Iterator set");
        
        ListIterator iterate = list1.listIterator(3);
        
        assertEquals("a", iterate.next());
        
        iterate.set("H");
        
        assertTrue(list1.contains("H"));
        assertEquals(3, list1.indexOf("H"));
        
        assertEquals("H", iterate.previous());
        
        iterate.set("Z");
        assertTrue(list1.contains("Z"));
        assertEquals(3, list1.indexOf("Z"));
        
        iterate.next();
        iterate.next();
        iterate.next();
        iterate.next();
        iterate.previous();
                
        iterate.set("Two");
        assertTrue(list1.contains("Two"));
        assertEquals(6, list1.indexOf("Two"));
    }
}
